package presentation.twitter;

import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import presentation.rest.ServiceLocator;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class TwitterService implements Serializable {

	private final Multimap<String, Tweet> userTweets;

	private final BiMap<Long, Tweet> tweets;

	private final Multimap<String, String> subscriptions;

	public TwitterService() {
		Multimap<String, Tweet> userTweets = HashMultimap.create();
		this.userTweets = Multimaps.synchronizedMultimap(userTweets);

		BiMap<Long, Tweet> tweets = HashBiMap.create();
		this.tweets = Maps.synchronizedBiMap(tweets);

		Multimap<String, String> subscriptions = HashMultimap.create();
		this.subscriptions = Multimaps.synchronizedMultimap(subscriptions);
	}

	public void addTweet(Tweet.Builder tweet) {

		Tweet newTweet = tweet
				.withTweetId(ServiceLocator.NEXT_TWITTER_ID.incrementAndGet())
				.build();

		userTweets.put(
				newTweet.getUsername(),
				newTweet
		);
		tweets.put(newTweet.getTweetId(), newTweet);
	}

	public void addComment(Comment comment) {
		Tweet tweet = tweets.get(comment.getTweetId());
		if (tweet != null) {
			tweet.addComment(comment);
		}
	}

	public List<Tweet> findTweets(String username) {
		ArrayList<Tweet> tweets = new ArrayList<Tweet>(this.userTweets.get(username));
		Collections.sort(tweets);
		return tweets;
	}

	public List<Tweet> findStream(String username) {
		List<Tweet> stream = new ArrayList<Tweet>();

		stream.addAll(userTweets.get(username));

		for (String u : subscriptions.get(username)) {
			stream.addAll(userTweets.get(u));
		}

		Collections.sort(stream);
		return stream;
	}

	public void addUsername(String username) {
		userTweets.put(username, null);
	}

	public void removeUsername(String username) {
		userTweets.removeAll(username);
	}

	public void follow(String subscriber, List<String> username) {
		if (userTweets.containsKey(subscriber)) {
			for (String u : username) {
				if (userTweets.containsKey(u)) {
					subscriptions.put(subscriber, u);
				}
			}
		}
	}
}
